import uuid
import redis
import time


class RedisLock(object):

    def __init__(self, t_redis):
        self.redis_client = t_redis

    def acquire_lock(self, name, acquire_time=5, time_out=300):
        identifier = str(uuid.uuid4())
        end = time.time() + acquire_time
        lock = "aladdin:case:lock:" + str(name)
        while time.time() < end:
            if self.redis_client.setnx(lock, identifier):
                # 给锁设置超时时间, 防止进程崩溃导致其他进程无法获取锁
                self.redis_client.expire(lock, time_out)
                return identifier
            elif not self.redis_client.ttl(lock):
                self.redis_client.expire(lock, time_out)
            time.sleep(0.1)
        return False

    def release_lock(self, name, identifier):
        lock = "aladdin:case:lock:" + str(name)
        pip = self.redis_client.pipeline(True)
        while True:
            try:
                pip.watch(lock)
                lock_value = self.redis_client.get(lock)
                if not lock_value:
                    return True
                if lock_value == identifier:
                    pip.multi()
                    pip.delete(lock)
                    pip.execute()
                    return True
                pip.unwatch()
                break
            except redis.exceptions.WatchError:
                pass
        return False
